package basics.jvm;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;

/**
 * 内存溢出 OOM - <span color="yellow">不要忘记修改JVM参数</span> {@code -Xmx8m -Xms8m}
 *
 * @author or2
 * @date 2021/7/20 9:22
 */
public class OOM {

    public static void main(String[] args) throws InterruptedException {
//        intuitive();
        badUseThreadPool();
    }

    /**
     * 错误使用线程池导致溢出
     */
    private static void badUseThreadPool() {
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() / 2);
        Stream.generate(new AtomicInteger()::getAndIncrement).forEach(integer -> fixedThreadPool.submit(() -> System.out.println(integer)));
    }

    /**
     * 使用 基本类型 直观感受线程溢出
     *
     * @throws InterruptedException
     */
    private static void intuitive() throws InterruptedException {
        //        初始JVM大约使用了4m大小的堆, 设置堆大小为8m, 使用4m的数组刚好溢出, 3m则不溢出
        int totalAmounts = 4 * 1024 * 1024 / 12;
//        int totalAmounts = 3 * 1024 * 1024 / 12;
        Integer[] ints = new Integer[totalAmounts];
        for (int i = 0; i < totalAmounts; i++) {
            ints[i] = i;
        }

//        可以通过 VisualVM 或 jconsole 进行观察, 调整参数
        TimeUnit.HOURS.sleep(1);
        for (Integer anInt : ints) {
            System.out.println(anInt);
        }
    }

}
